<?php
namespace app\service;

use app\model\User as ModelUser;
use think\facade\Cache;

class UserService
{

    // Redis用户信息前缀
    private $redisPrefix = 'token:';


    // 用户 token 集合前缀
    protected string $tokenSetPrefix = 'user_tokens:';
    // Token过期时间(秒)
    private $tokenExpire = 3600; // 1天

    // 处理登录请求
    public function login($username, $password)
    {
        $user = ModelUser::where('username', $username)->find();
        if ($user && password_verify($password, $user['password'])) {

            // //生成唯一的用户token
            // $token = md5(uniqid() . $user['id'] . time());

             // 存储用户信息到Redis
            $userData = [
                'id' => $user['id'],
                'username' => $user['username'],
                'nickname' => $user['nickname'],
                'email' => $user['email'],
                'status' => $user['status'],
                'role' => $user['role']
            ];

            $token = $this->generateToken($userData);

            // // 设置Redis缓存，使用token作为键
            // Cache::store('redis')->set($this->redisPrefix . $token, $userData, $this->tokenExpire);

            // // 登录成功，保存用户信息到会话
            // Session::set('user_id', $user['id']);
            // Session::set('username', $user['username']);

            return json([
                'code' => 200, 
                'msg' => "登录成功",
                'data' => [
                        'token' => $token,
                        'userInfo' => Cache::store('redis')->get($this->redisPrefix . $token) //Cache::store('redis')->get($this->redisPrefix . $token);
            ]]);
        } else {
            // 登录失败
            return json(['code' => 401, 'msg' => "账户或密码错误"]);
        }

    }

    // 处理注册请求
    public function register($username, $password, $confirmPassword)
    {
        try {
            // 检查用户名是否已存在
            $existingUser = ModelUser::where('username', $username)->find();
            if ($existingUser) {
                return json(['code' => 400, 'msg' => '用户名已存在']);
            }

            // 验证数据
            if (empty($username) || empty($password)) {
                return json(['code' => 400, 'msg' => '用户名和密码不能为空']);
            }

            if ($password !== $confirmPassword) {
                return json(['code' => 400, 'msg' => '两次输入的密码不一致']);
            }

            // 创建新用户
            $user           = new ModelUser();
            $user->username = $username;
            $user->password = password_hash($password, PASSWORD_BCRYPT);
            $user->save();

            return json(['code' => 200, 'msg' => '注册成功']);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '注册失败：' . $e->getMessage()]);
        }
    }

    // 处理登出请求
    public function logout($token)
    {
        $redis = Cache::store('redis');
         $redis->multi();
        // 从Redis中删除token
        $redis->del($this->redisPrefix . $token);
        $redis->exec();
        return json(['code' => 200, 'msg' => '登出成功']);
    }

    // 检查登录状态
    public function isLogin($token): bool
    {
        if (empty($token)) {
            return false;
        }
        
        $userData = Cache::store('redis')->get($this->redisPrefix . $token);
        return !empty($userData);
    }

    public function updatePassword($username , $password , $newPassword)
    {
        try {
            // 验证用户
            $user = ModelUser::where('username', $username)->find();
            // 验证密码 (假设密码已哈希存储)
            if ($user && password_verify($password, $user['password'])) {
                $hash           = password_hash($newPassword, PASSWORD_BCRYPT);
                $user->password = $hash;
                $user->save();

                // // 删除该用户的所有活跃token (强制重新登录)
                $this->deleteAllTokensForUser($user['id']);

                return json([
                    'code' => 200,
                    'msg'  => "密码修改成功"
                ]);
            } else {
                return json([
                    'code' => 400,
                    'msg'  => "用户不存在或者密码不正确",
                ]);
            }
        } catch (\Exception $e) {
            return json([
                'code' => 400,
                'msg'  => $e->getMessage(),
            ]);
        }
    }

    public function getUser($token){
       $userData = Cache::store('redis')->get($this->redisPrefix . $token);
        if (empty($userData)) {
            return null;
        }
        
        // // 刷新token过期时间
        // Cache::store('redis')->set($this->redisPrefix . $token, $userData, $this->tokenExpire);
        
        // 返回用户信息，去除敏感字段
        return [
            'nickname' => $userData['nickname'],
            'email' => $userData['email'],
            'status' => $userData['status'],
            'role' => $userData['role'],
        ];
    }


     /**
     * 创建并保存 token
     *
     * @param array $userData 用户信息数组（包含至少 user_id）
     * @return string 生成的 token
     */
    public function generateToken(array $userData): string
    {
        $token = uniqid() . bin2hex(random_bytes(8));
        $userId = $userData['id'] ?? null;

        if (!$userId) {
            throw new \Exception('用户数据中缺少ID');
        }
        
        $redis = Cache::store('redis');
        $expireTime = time() + $this->tokenExpire;

        // 保存 token -> 用户信息
        $redis->set(
            $this->redisPrefix . $token,
            $userData,
            $this->tokenExpire
        );

        // 使用 ZSET 存储，score 为过期时间
        $redis->zAdd($this->tokenSetPrefix . $userId, $expireTime, $token);
        
        // 让整个 ZSET 也有过期时间（设置为最长 token 过期时间 + 缓冲时间）
        $redis->expire($this->tokenSetPrefix . $userId, $this->tokenExpire + 3600);

        return $token;
    }

    /**
     * 根据 token 获取用户信息
     *
     * @param string $token
     * @return array|null
     */
    public function getUserByToken(string $token): ?array
    {
        return Cache::store('redis')->get($this->redisPrefix . $token);
    }

    /**
     * 删除指定 token（退出当前设备）
     *
     * @param string $token
     * @return bool
     */
    public function deleteToken(string $token): bool
    {
        $userData = $this->getUserByToken($token);

        if ($userData && isset($userData['id'])) {
            $userId = $userData['id'];
            Cache::store('redis')->sRem($this->tokenSetPrefix . $userId, $token);
        }

        return Cache::store('redis')->delete($this->redisPrefix . $token);
    }

    /**
     * 删除该用户的所有 token（退出所有设备）
     *
     * @param int|string $userId
     * @return int 成功删除的 token 数量
     */
    public function deleteAllTokensForUser($userId): int
    {
        $key = $this->tokenSetPrefix . $userId;
        $tokens = Cache::store('redis')->sMembers($key);
        $deleted = 0;

        if (!empty($tokens)) {
            foreach ($tokens as $token) {
                Cache::store('redis')->delete($this->redisPrefix . $token);
                $deleted++;
            }
            Cache::store('redis')->delete($key);
        }

        return $deleted;
    }

    /**
     * 设置 token 过期时间（可链式调用）
     *
     * @param int $seconds
     * @return $this
     */
    public function setTokenExpire(int $seconds): self
    {
        $this->tokenExpire = $seconds;
        return $this;
    }

}
